#!/usr/bin/env python
# -*- encoding: utf-8 -*-

import time
import json

from .sqlitebase import SQLiteMixin, SplitTableMixin
from pyspider.database.base.errordb import ErrorDB as BaseErrorDB
from pyspider.database.basedb import BaseDB


class ErrorDB(SQLiteMixin, SplitTableMixin, BaseErrorDB, BaseDB):
    __tablename__ = 'errordb'
    placeholder = '?'

    def __init__(self, path):
        self.path = path
        self.last_pid = 0
        self.conn = None
        self._create_project()

    def _create_project(self):
        res = self._select('sqlite_master', what='COUNT(*)',
                           where='`type` = "table" and `name` = %s' % self.placeholder,
                           where_values=(self.__tablename__,))
        if not next(res)[0]:
            self._execute('''CREATE TABLE IF NOT EXISTS `%s` (
                    taskid PRIMARY KEY,
                    project, url, status,
                    schedule, fetch, process, track,
                    lastcrawltime, updatetime, mark,
                    errortype, result, `group`,
                    project_updatetime, project_md5sum
                    )''' % self.__tablename__)
            self._execute(
                '''CREATE INDEX `errortype_%s_index` ON %s (errortype)'''
                % (self.__tablename__, self.escape(self.__tablename__))
            )

    @staticmethod
    def _parse(data):
        for each in ('schedule', 'fetch', 'process', 'track', 'result'):
            data[each] = json.loads(data[each]) if data.get(each, None) else {}
        return data

    @staticmethod
    def _stringify(data):
        for each in ('schedule', 'fetch', 'process', 'track', 'result'):
            if each in data:
                data[each] = json.dumps(data[each])
        return data

    def get_tasks(self, error_type, mark=False, limit=1000):
        where = '`errortype` = %s and `mark` = %s' % (self.placeholder, self.placeholder)
        return [self._parse(each) for each in self._select2dic(
            self.__tablename__, where=where,
            where_values=(error_type, mark,), limit=limit)]

    def get_task(self, project, taskid):
        where = "`project` = {ph} and `taskid` = {ph}".format(ph=self.placeholder)
        for each in self._select2dic(self.__tablename__, where=where, where_values=(project, taskid)):
            return self._parse(each)
        return None

    def insert(self, project, taskid, obj):
        obj = dict(obj)
        obj['taskid'] = taskid
        obj['project'] = project
        obj['updatetime'] = time.time()
        obj['mark'] = False
        return self._insert(self.__tablename__, **self._stringify(obj))

    def update(self, project, taskid, obj):
        obj = dict(obj)
        return self._update(
            self.__tablename__, where="`taskid` = {}".format(self.placeholder), where_values=(taskid, ),
            **self._stringify(obj)
        )

    def count(self, error_type, hour=None):
        if hour:
            return next(self._select(
                self.__tablename__, what='COUNT(*)',
                where='`errortype` = {ph} and `mark` = {ph} and `updatetime` > {ph}'.format(ph=self.placeholder),
                where_values=(error_type, False, time.time() - hour * 3600)))[0]
        return next(self._select(
            self.__tablename__, what='COUNT(*)',
            where='`errortype` = {ph} and `mark` = {ph}'.format(ph=self.placeholder),
            where_values=(error_type, False)))[0]
